﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Emgu.CV;
using System.IO;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms;

namespace SoundPlugin
{
    public class Shape : INotifyPropertyChanged
    {
        #region Properties

        private Color color;
        public Color Color
        {
            get { return color; }
            set 
            { 
                color = value;
                if (color != null) 
                {
                    this.HighlightColor = ControlPaint.Light(color, 0.9f);
                }
            }
        }

        private Color highlightColor;
        public Color HighlightColor
        {
            get { return highlightColor; }
            set { highlightColor = value; }
        }

        private FileInfo soundFile;
        public FileInfo SoundFile
        {
            get { return soundFile; }
            set { soundFile = value; }
        }

        private Contour<Point> contour;
        public Contour<Point> Contour
        {
            get { return contour; }
            set { contour = value; }
        }

        private bool process;
        private ReaderWriterLockSlim processLock = new ReaderWriterLockSlim();
        public bool Process
        {
            get 
            {
                try
                {
                    processLock.EnterReadLock();
                    return process;
                }
                finally 
                {
                    processLock.ExitReadLock();
                }
            }
            set 
            {
                try
                {
                    processLock.EnterWriteLock();
                    process = value;
                }
                finally 
                {
                    processLock.ExitWriteLock();
                }
            }
        }

        private bool isPaused;
        private ReaderWriterLockSlim pauseLock = new ReaderWriterLockSlim();
        public bool IsPaused
        {
            get
            {
                try
                {
                    pauseLock.EnterReadLock();
                    return isPaused;
                }
                finally
                {
                    pauseLock.ExitReadLock();
                }
            }
            set
            {
                try
                {
                    pauseLock.EnterWriteLock();
                    isPaused = value;
                }
                finally
                {
                    pauseLock.ExitWriteLock();
                }
            }
        }

        private ShapeSoundProcessor processor;
        public ShapeSoundProcessor Processor
        {
            get { return processor; }
            set { processor = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info) 
        {
            if (PropertyChanged != null) 
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        private bool isActive;
        private ReaderWriterLockSlim isActiveLock = new ReaderWriterLockSlim();
        public bool IsActive
        {
            get 
            {
                try
                {
                    isActiveLock.EnterReadLock();
                    return isActive;
                }
                finally 
                {
                    isActiveLock.ExitReadLock();
                }
            }
            set 
            {
                try
                {
                    isActiveLock.EnterWriteLock();
                    if (value != this.isActive)
                    {
                        isActive = value;
                        NotifyPropertyChanged(value.ToString());
                    }
                }
                finally 
                {
                    isActiveLock.ExitWriteLock();
                }
            }
        }
        #endregion

        #region Constructor
        public Shape() 
        { 
        
        }

        public Shape(Contour<Point> contour , Color color) 
        {
            this.Color = color;
            this.Contour = contour;
            this.IsPaused = false;
            this.Process = false;
        }
        #endregion

        #region Public Methods
        public void ProcessShape() 
        {
            while (this.Process) 
            {
                if (!this.isPaused)
                {
                    List<Spat> markers = new List<Spat>(PluginModel.Instance.MarkerPositions);
                    foreach (Spat spat in markers)
                    {
                        Point? center = spat.getCenter();
                        if (center != null)
                        {
                            if (this.Contour.InContour((Point)center) >= 0)
                            {
                                if (this.SoundFile != null)
                                {
                                    this.IsActive = true;
                                    this.processor.PlaySound(this, true, false);
                                    this.IsActive = false;
                                }
                            }
                        }
                    }
                }
                Thread.Sleep(40);
            }
        }
        #endregion
    }
}
